package cn.growthgate.fgo.web;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.shiro.authz.annotation.RequiresUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;

import cn.growthgate.fgo.common.base.BaseVo;
import cn.growthgate.fgo.entity.Class;
import cn.growthgate.fgo.entity.Cv;
import cn.growthgate.fgo.entity.MyServant;
import cn.growthgate.fgo.entity.Painter;
import cn.growthgate.fgo.entity.Servant;
import cn.growthgate.fgo.entity.ServantWhite;
import cn.growthgate.fgo.entity.enums.ServantGet;
import cn.growthgate.fgo.entity.enums.ServantPropB;
import cn.growthgate.fgo.entity.enums.ServantTrait;
import cn.growthgate.fgo.service.IClassService;
import cn.growthgate.fgo.service.ICvService;
import cn.growthgate.fgo.service.IMyServantBondService;
import cn.growthgate.fgo.service.IMyServantService;
import cn.growthgate.fgo.service.IPainterService;
import cn.growthgate.fgo.service.IServantBondService;
import cn.growthgate.fgo.service.IServantService;
import cn.growthgate.fgo.service.IServantWhiteService;
import cn.growthgate.fgo.util.DateUtils;
import cn.growthgate.fgo.util.StringUtils;
import cn.growthgate.fgo.web.result.JsonResult;
import cn.growthgate.fgo.web.result.TableResult;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author GrowthGate
 * @since 2019-01-20
 */
@Controller
@RequestMapping("/myServant")
@RequiresUser
public class MyServantController {

	@Autowired
	private IMyServantService myServantService;

	@Autowired
	private IServantService servantService;

	@Autowired
	private IClassService classService;

	@Autowired
	private ICvService cvService;

	@Autowired
	private IPainterService painterService;

	@Autowired
	private IMyServantBondService myServantBondService;

	@Autowired
	private IServantBondService servantBondService;

	@Autowired
	private IServantWhiteService servantWhiteService;

	@RequestMapping("/list")
	public ModelAndView list() {
		List<Class> classes = classService.selectAll();
		List<Map<String, Object>> stars = new ArrayList<>();
		for (int i = 0; i <= 5; i++) {
			Map<String, Object> map = new HashMap<>();
			map.put("value", i);
			map.put("desc", "★ " + i);
			stars.add(map);
		}
		List<Cv> cvs = cvService.selectAll();
		List<Painter> painters = painterService.selectAll();

		return new ModelAndView("myServant/list").addObject("classes", classes).addObject("stars", stars)
				.addObject("cvs", cvs).addObject("painters", painters);
	}

	@ResponseBody
	@RequestMapping("/tableData")
	public TableResult<BaseVo<MyServant>> tableData(Servant entity, Long cvId, ServantTrait trait, Integer current,
			Integer size, String orderByField, Boolean isAsc) {
		Wrapper<MyServant> wrapper = new EntityWrapper<>();

		// 防止只有order by的情况下sql语句报错
		wrapper.where("1 = 1");
		if (entity.getClassId() != null) {
			wrapper.eq("s.classId", entity.getClassId());
		}
		if (entity.getStar() != null) {
			wrapper.eq("s.star", entity.getStar());
		}
		if (entity.getCost() != null) {
			wrapper.eq("s.cost", entity.getCost());
		}
		if (entity.getFaction() != null) {
			wrapper.eq("s.faction", entity.getFaction());
		}
		if (entity.getGet() != null) {
			wrapper.like("s.get", entity.getGet());
		}
		if (entity.getNpColorCard() != null) {
			wrapper.eq("s.npColorCard", entity.getNpColorCard());
		}
		if (entity.getNpType() != null) {
			wrapper.eq("s.npType", entity.getNpType());
		}
		if (entity.getCards() != null) {
			wrapper.eq("s.cards", entity.getCards());
		}
		if (entity.getSex() != null) {
			wrapper.eq("s.sex", entity.getSex());
		}
		if (entity.getPropA() != null) {
			wrapper.eq("s.propA", entity.getPropA());
		}
		if (entity.getPropB() != null) {
			if (entity.getPropB() == ServantPropB.GOOD || entity.getPropB() == ServantPropB.EVIL) {
				// 允许同时搜索复合属性的从者
				wrapper.in("s.propB", Arrays.asList(entity.getPropB(), ServantPropB.GOOD_EVIL));
			} else {
				wrapper.eq("s.propB", entity.getPropB());
			}
		}
		if (trait != null) {
			wrapper.eq("st.trait", trait);
		}
		if (cvId != null) {
			wrapper.eq("sc.cvId", cvId);
		}
		if (entity.getPainterId() != null) {
			wrapper.eq("s.painterId", entity.getPainterId());
		}
		if (StringUtils.isNotBlank(entity.getName())) {
			wrapper.andNew().like("s.name", entity.getName()).or().like("s.jName", entity.getName()).or()
					.like("s.eName", entity.getName()).or().like("s.nickName", entity.getName());
		}
		if (StringUtils.isNotBlank(orderByField) && isAsc != null) {
			if ("servantGameId".equals(orderByField)) {
				orderByField = "s.gameId";
			} else if ("getDays".equals(orderByField)) {
				orderByField = "ms.getDate";
				isAsc = !isAsc;
			} else {
				// 加上myServant表的别名
				orderByField = "ms." + orderByField;
			}
		}

		Page<MyServant> page = myServantService.selectJoinServant(current, size, orderByField, isAsc, wrapper);
		return new TableResult<BaseVo<MyServant>>(myServantService.transformVo(page));
	}

	@RequestMapping("/form")
	public ModelAndView form(Long id) {
		MyServant entity = myServantService.selectById(id);
		Servant servant = null;
		if (entity != null) {
			servant = servantService.selectById(entity.getServantId());
		}
		List<Servant> servants = servantService.selectAll();

		return new ModelAndView("myServant/form").addObject("entity", entity).addObject("servant", servant)
				.addObject("servants", servants);
	}

	@ResponseBody
	@RequestMapping("/save")
	public JsonResult save(@Validated MyServant myServant, BindingResult bindingResult) {
		if (bindingResult.hasErrors()) {
			return JsonResult.fail(bindingResult.getAllErrors().get(0).getDefaultMessage());
		}
		// 判断是否是允许保存的从者
		Servant servant = servantService.selectById(myServant.getServantId());
		if (servant == null) {
			return JsonResult.fail("不存在的从者");
		} else if (servant.getGets().contains(ServantGet.IMPOSSIBLE)) {
			// 无法获得
			return JsonResult.fail("无法添加此从者");
		}
		// 判断当前值与目标值是否合法
		if (myServant.getStage() != null && myServant.getToStage() != null
				&& (int) myServant.getStage().getValue() > (int) myServant.getToStage().getValue()) {
			return JsonResult.fail("当前再临阶段不能大于目标再临阶段");
		}
		if (myServant.getSkill1() != null && myServant.getToSkill1() != null
				&& myServant.getSkill1() > myServant.getToSkill1()) {
			return JsonResult.fail("当前技能1等级不能大于目标技能1等级");
		}
		if (myServant.getSkill2() != null && myServant.getToSkill2() != null
				&& myServant.getSkill2() > myServant.getToSkill2()) {
			return JsonResult.fail("当前技能2等级不能大于目标技能2等级");
		}
		if (myServant.getSkill3() != null && myServant.getToSkill3() != null
				&& myServant.getSkill3() > myServant.getToSkill3()) {
			return JsonResult.fail("当前技能3等级不能大于目标技能3等级");
		}
		// 从者面板
		if (myServant.getLevel() != null) {
			ServantWhite selectWhite = servantWhiteService.selectWhite(myServant.getServantId(), myServant.getLevel());
			if (selectWhite != null) {
				if (ObjectUtils.allNotNull(myServant.getFfHp(), selectWhite.getHp())) {
					myServant.setHp(myServant.getFfHp() + selectWhite.getHp());
				} else {
					myServant.setHp(null);
				}
				if (ObjectUtils.allNotNull(myServant.getFfAtk(), selectWhite.getAtk())) {
					myServant.setAtk(myServant.getFfAtk() + selectWhite.getAtk());
				} else {
					myServant.setAtk(null);
				}
			}
		}
		// 今天
		Date today = DateUtils.getTodayStart();
		Integer bondValue = myServant.getBondValue();
		if (bondValue != null) {
			// 获取羁绊等级
			int bondLevel = servantBondService.getLevelByValue(myServant.getServantId(), bondValue);
			myServant.setBondLevel(bondLevel);
		}
		myServantService.insertOrUpdate(myServant);
		// 获得日期
		if (myServant.getGetDate() != null) {
			// 获得日期当天羁绊为0
			if (bondValue != null) {
				// 记录今天羁绊值
				myServantBondService.insertOrUpdateByDate(myServant.getId(), today, myServant.getBondLevel(),
						myServant.getBondValue());
			}
			myServantBondService.insertOrUpdateByDate(myServant.getId(), myServant.getGetDate(), 0, 0);
			// 平均每日羁绊
			Integer dailyBond = myServantBondService.getDailyBond(myServant.getId());
			myServant.setDailyBond(dailyBond);
			myServantService.updateById(myServant);
		}
		return JsonResult.ok();
	}

	@ResponseBody
	@RequestMapping("/delete")
	public JsonResult delete(Long[] ids) {
		if (myServantService.deleteBatchIds(Arrays.asList(ids))) {
			myServantBondService.deleteByMyServantIds(Arrays.asList(ids));
			return JsonResult.ok("删除成功");
		} else {
			return JsonResult.fail("删除失败");
		}
	}

	@ResponseBody
	@RequestMapping("/getServants")
	public TableResult<Servant> getServants(String keyword, Integer current, Integer size, String orderByField,
			Boolean isAsc) {
		Wrapper<Servant> wrapper = new EntityWrapper<>();

		// 不包含无法获得的从者
		wrapper.ne("get", ServantGet.IMPOSSIBLE);
		if (StringUtils.isNotBlank(keyword)) {
			wrapper.andNew().eq("gameId", keyword).or().like("name", keyword).or().like("jName", keyword).or()
					.like("eName", keyword).or().like("nickName", keyword);
		}

		Page<Servant> page = servantService.selectPage(current, size, orderByField, isAsc, wrapper);
		return new TableResult<Servant>(page);
	}

}
